package API.Class.util.TCP.Client;

import API.Class.Collections.SameThreadCollections;
import API.Class.util.TCP.Interactions;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TCP_Client {
    static SameThreadCollections<Socket> sameThreadCollections;
    private String ServerIP;//服务器IP地址
    private int ServerPort;//服务器端口
    private Thread t;
    // 声明一个Class类型的变量interactions，用于存储Runnable的子类
    private final Class<? extends Callable> interactions;

    //设置服务器IP
    public void SetServerIP(String ServerIP) {
        this.ServerIP = ServerIP;
    }

    public void SetServerPort(int ServerPort) {
        this.ServerPort = ServerPort;
    }

    static {
        if (sameThreadCollections == null) sameThreadCollections = new SameThreadCollections<>();
    }

    public TCP_Client(String ServerIP, int ServerPort, Class<? extends Callable> interactions) {
        this.interactions = interactions;
        this.ServerIP = ServerIP;
        this.ServerPort = ServerPort;
    }

    public void Connect() throws IOException {
        String IP = ServerIP;
        int Port = ServerPort;
        sameThreadCollections.Add(new Socket(IP, Port));
        Constructor constructor = null;
        Interactions interactions1 = null;
        try {
            constructor = interactions.getConstructor(Socket.class);
            interactions1 = (Interactions) constructor.newInstance(sameThreadCollections.Get());
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        FutureTask futureTask = new FutureTask<>(interactions1);
        t = new Thread(futureTask);
        t.start();
    }

    public void Close() throws IOException {
        t.interrupt();
        sameThreadCollections.Get().close();
    }


    public Socket GetSocket() {
        return sameThreadCollections.Get();
    }

    /**
     * 查看ip地址是否配置正确
     *
     * @param IP IP地址
     * @return
     */
    public static boolean MatchIP(String IP) {
        String regex = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\\.){3}|([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|localhost)$";

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(IP);

        return matcher.matches();
    }

    /**
     * 检查port是否配置正确
     *
     * @param port 端口
     * @return
     */
    public static boolean MatchPort(int port) {
        return (port >= 0) && (port <= 65535);
    }

    /**
     * 综合检查是否正确
     *
     * @param IP   IP地址
     * @param port 端口
     * @return
     */
    public static boolean Match(String IP, int port) {
        return MatchIP(IP) && MatchPort(port);
    }
}
